#include "unit.h"

static uint8_t flag_is_running = 0;

volatile uint16_t plc_tokenSeed = 1;

/**
 * @brief Get the token object
 *
 * @param token
 */
void get_token(char *token)
{
	if (plc_tokenSeed >= 65535)
		plc_tokenSeed = 0;

	sprintf(token, "%d", plc_tokenSeed);

	plc_tokenSeed++;
}

/**
 * @brief  itobcd
 * @param  data: int data
 * @retval BCD data
 * @note
 */
uint8_t itobcd(uint8_t data)
{

	return (((data / 10 << 4) & 0xf0) | ((data % 10) & 0x0f));
}

/**
 * @brief  get the timestamp string
 * @param  psDateTime: string of get the system timestamp
 * @retval none
 * @note
 */
void mqtt_get_time(char *psDateTime)
{
	struct timeval tv;
	struct timezone tz;
	struct tm *pTM;

	gettimeofday(&tv, &tz);
	pTM = localtime(&tv.tv_sec);

	sprintf(psDateTime, "%04d-%02d-%02dT%02d:%02d:%02d",
			pTM->tm_year + 1900, pTM->tm_mon + 1, pTM->tm_mday,
			pTM->tm_hour, pTM->tm_min, pTM->tm_sec);
}

void delay_ms(unsigned long mSec)
{
	struct timeval tv;
	tv.tv_sec = mSec / 1000;
	tv.tv_usec = (mSec % 1000) * 1000;
	int err;
	do
	{
		err = select(0, NULL, NULL, NULL, &tv);
	} while (err < 0 && errno == EINTR);
}

/**
 * @brief  set_app_running setting
 * @param  str:
 * @param  out:
 * @param  outlen:
 * @retval None
 */
int AtoH(char *str, uint8_t *out)
{
	char *p = str;

	char high = 0;
	char low = 0;

	int tmplen = 0;
	int cnt = 0;

	if ((str == NULL) || ((out == NULL)))
	{
		return 0;
	}

	tmplen = strlen(p);

	if (tmplen == 0)
	{
		return 0;
	}

	while (cnt < (tmplen / 2))
	{
		high = ((*p > '9') && ((*p <= 'F') || (*p <= 'f'))) ? *p - 48 - 7 : *p - 48;
		low = (*(++p) > '9' && ((*p <= 'F') || (*p <= 'f'))) ? *(p)-48 - 7 : *(p)-48;

		out[cnt] = ((high & 0x0f) << 4 | (low & 0x0f));

		p++;
		cnt++;
	}

	if (tmplen % 2 != 0)
	{
		out[cnt] = ((*p > '9') && ((*p <= 'F') || (*p <= 'f'))) ? *p - 48 - 7 : *p - 48;
	}

	return tmplen / 2 + tmplen % 2;
}

/**
  * @brief  获取时间戳字符串
  * @param  null
  * @retval null
  */
int get_current_time_global(char *DateTime)
{
    struct tm *t;
	time_t tt;
	time(&tt);
	t=localtime(&tt);
    sprintf(DateTime,"%04d-%02d-%02dT%02d:%02d:%02d.000+0800",(1900 + t->tm_year),(1 + t->tm_mon),t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);

	return 0;
}

/**
 * @brief Get the system time us object
 *
 * @return uint64_t
 */
uint64_t get_system_time_us(void)
{
	struct timeval now;

	gettimeofday(&now, NULL);

	return (uint64_t)(now.tv_sec * 1000000L + now.tv_usec);
}

/**
 * @brief Get the system time absoffset object
 *
 * @param current
 * @param last
 * @return uint64_t
 */
uint64_t get_system_time_absoffset(uint64_t current, uint64_t last)
{
	if (current >= last)
		return (current - last);
	else
		return (uint64_t)((0xffffffffffffffff - last) + current);
}
